package com.example.easyexcel.excelOld.util;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.handler.WriteHandler;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import lombok.extern.log4j.Log4j2;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;

import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.util.List;

@Log4j2
public class ExcelUtil {
    /**
     * 导出 Excel
     *
     * @param response  :响应
     * @param data      :导出的list集合
     * @param fileName  :Excel名（最好英文，无需后缀）
     * @param sheetName :sheet页名
     * @param clazz     :导出Excel实体类
     * @throws Exception
     */
    public static void writeExcel(HttpServletResponse response, List<? extends Object> data, String fileName, String sheetName, Class clazz) throws Exception {
        //表头样式
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        //设置表头居中对齐
        headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        //内容样式
        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
        //设置内容靠左对齐
        contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.LEFT);
        HorizontalCellStyleStrategy horizontalCellStyleStrategy = new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);

        EasyExcel.write(getOutputStream(fileName, response), clazz)
                .excelType(ExcelTypeEnum.XLSX)//读取的文件类型
                .sheet(sheetName)//读取的sheet,可以是行号也可以是sheet名
//                .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())//设置自动适应宽度
                .registerWriteHandler(horizontalCellStyleStrategy)//设置样式(或：registerWriteHandler(createStyleStrategy))
                .doWrite(data);
    }


    /**
     * 导出 Excel
     *
     * @param response  :响应
     * @param data      :导出的list集合
     * @param fileName  :Excel名（最好英文，无需后缀）
     * @param sheetName :sheet页名
     * @param clazz     :导出Excel实体类
     * @throws Exception
     */
    public static void writeErrorExcel(HttpServletResponse response, List<? extends Object> data, String fileName, String sheetName, Class clazz, WriteHandler commentWriteHandler) throws Exception {
        //表头样式
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        //设置表头居中对齐
        headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        //内容样式
        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
        //设置内容靠左对齐
        contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.LEFT);
        HorizontalCellStyleStrategy horizontalCellStyleStrategy = new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);

        EasyExcel.write(getOutputStream(fileName, response), clazz)
                .excelType(ExcelTypeEnum.XLSX)//读取的文件类型
                .inMemory(Boolean.TRUE)
                .sheet(sheetName)//读取的sheet,可以是行号也可以是sheet名
//                .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())//设置自动适应宽度
                .registerWriteHandler(horizontalCellStyleStrategy)//设置样式(或：registerWriteHandler(createStyleStrategy))
                //注册批注拦截器
                .registerWriteHandler(commentWriteHandler)
                .doWrite(data);
    }
    /**
     * 格式处理
     */
    private static OutputStream getOutputStream(String fileName, HttpServletResponse response) throws Exception {
        response.setContentType("application/vnd.ms-excel;charset=utf-8");
        response.setCharacterEncoding("utf8");
        response.addHeader("Content-disposition", "attachment;filename=" + fileName + ExcelTypeEnum.XLSX.getValue());
        return response.getOutputStream();
    }

    /**
     * 自定义样式
     */
    private static HorizontalCellStyleStrategy createStyleStrategy() {
        // 头的策略
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        // 背景设置为红色
        headWriteCellStyle.setFillForegroundColor(IndexedColors.LIGHT_CORNFLOWER_BLUE.getIndex());
        WriteFont headWriteFont = new WriteFont();
        headWriteFont.setFontHeightInPoints((short) 10);
        headWriteCellStyle.setWriteFont(headWriteFont);
        // 内容的策略
        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
        contentWriteCellStyle.setBorderBottom(BorderStyle.THIN);  //底边框
        contentWriteCellStyle.setBorderLeft(BorderStyle.THIN);  //左边框
        contentWriteCellStyle.setBorderRight(BorderStyle.THIN);  //右边框
        contentWriteCellStyle.setBorderTop(BorderStyle.THIN);  //顶边框
        WriteFont contentWriteFont = new WriteFont();
        // 字体大小
        contentWriteFont.setFontHeightInPoints((short) 10);
        contentWriteCellStyle.setWriteFont(contentWriteFont);
        // 执行策略
        HorizontalCellStyleStrategy horizontalCellStyleStrategy =
                new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);

        return horizontalCellStyleStrategy;
    }

//    /**
//     * 导入 Excel
//     *
//     * @param multipartFile excel文件
//     * @param clazz         数据类型的class对象
//     * @param <T>
//     * @return
//     */
//    public static <T> void importExcel(MultipartFile multipartFile, Class<T> clazz) throws Exception {
//        List<T> list = new ArrayList<>();
//        InputStream inputStream = multipartFile.getInputStream();
//
//        EasyExcel.read(inputStream, clazz, new AnalysisEventListener<T>() {
//            //每解析一行就会调用一次，data数据表示解析出来一行的数据
//            @Override
//            public void invoke(T data, AnalysisContext context) {
//                list.add(data);
//            }
//
//            //当全部数据读取完成后调用该方法
//            @Override
//            public void doAfterAllAnalysed(AnalysisContext context) {
//            }
//        }).sheet().doRead();
//
//    }

    /**
     * 获取Excel单元格的索引
     *
     * @param obj        JavaBean对象
     * @param fieldValue JavaBean字段值
     * @return
     */
    public static Integer getCellIndex(Object obj, String fieldValue) {
        try {
            Field declaredField = obj.getClass().getDeclaredField(fieldValue);
            ExcelProperty annotation = declaredField.getAnnotation(ExcelProperty.class);
            if (annotation == null) {
                return null;
            }
            return annotation.index();
        } catch (NoSuchFieldException e) {
            log.error("error:", e);
        }
        return null;
    }
}
